#include "threadPool.h"

int response(train_t* pResponse, int netfd, char *msg)
{
    send(netfd, &pResponse->type, sizeof(pResponse->type), MSG_NOSIGNAL);
    pResponse->length = strlen(msg);
    memcpy(pResponse->value, msg, pResponse->length);
    send(netfd, &pResponse->length, sizeof(pResponse->length), MSG_NOSIGNAL);
    send(netfd, pResponse->value, pResponse->length, MSG_NOSIGNAL);
    return 0;
}

void *threadWorker(void *arg)
{
    threadPool_t *pThreadPool = (threadPool_t *)arg;
    while(1)
    {
        pthread_mutex_lock(&pThreadPool->mutex);
        while(pThreadPool->exitFlag == 0 && pThreadPool->taskQueue.queueSize == 0)
        {
            pthread_cond_wait(&pThreadPool->cond, &pThreadPool->mutex);
        }
        if(pThreadPool->exitFlag == 1)
        {
            pthread_mutex_unlock(&pThreadPool->mutex);
            printf("workerTherad exit.\n");
            pthread_exit(NULL);
        }
        int netfd = pThreadPool->taskQueue.head->netfd;
        deQueue(&pThreadPool->taskQueue);
        pthread_mutex_unlock(&pThreadPool->mutex);
        printf("workerThread got netfd = %d\n", netfd);
        UsrInfo_t UserInfo;
        UsrInfoInit(&UserInfo);
        // business begin
        while(1)
        {
            train_t train;
            train_t response_msg;
            char pwd[1024] = {0};
            response_msg.type = RESPONSE;
            memset(&train, 0, sizeof(train));
            ssize_t ret = recv(netfd, &train.type, sizeof(train.type), MSG_WAITALL);
            if (ret <= 0) {  // 连接异常或关闭
                printf("Client %d disconnected.\n", netfd);
                break;
            }
            recv(netfd, &train.length, sizeof(train.length), MSG_WAITALL);
            if(train.length){
                recv(netfd, train.value, train.length, MSG_WAITALL);
            }
            switch(train.type)
            {
            case CMD_CD:
                printf("cd %s\n", train.value);
                ret = cmd_cd(&UserInfo, train.value);
                if(ret == -1)
                    response(&response_msg, netfd, "目录不存在！");
                else
                    response(&response_msg, netfd, "OK");
                break;
            case CMD_LS:
                printf("cmd_ls\n");
                char list_buf[4096] = {0};
                ret = cmd_ls(&UserInfo, list_buf, sizeof(list_buf));
                if(ret == 0)
                    response(&response_msg, netfd, list_buf);
                else
                    response(&response_msg, netfd, "ls failed.\n");
                break;
            case CMD_PWD:
                printf("cmd_pwd\n");
                // cmd_pwd(&UserInfo, pwd, sizeof(pwd));
                new_cmd_pwd(&UserInfo, pwd);
                response(&response_msg, netfd, pwd);
                break;
            case CMD_PUTS:
                printf("cmd_puts\n");
                printf("client puts file,fileName: %s\n", train.value);
                ret = cmd_puts(train.value, &UserInfo, netfd);
                if(ret == 0)
                    response(&response_msg, netfd, "finish puts.\n");
                else
                    response(&response_msg, netfd, "puts failed.\n");
                break;
            case CMD_GETS:
                printf("cmd_gets\n");
                printf("client gets file,fileName: %s\n", train.value);
                ret = cmd_gets(train.value, &UserInfo, netfd);
                if(ret == 0)
                    response(&response_msg, netfd, "finish gets.\n");
                else
                    response(&response_msg, netfd, "gets failed.\n");
                break;
            case CMD_RM:
                printf("cmd_rm\n");
                ret = cmd_rm(UserInfo, train.value);
                if(ret == 0)
                    response(&response_msg, netfd, "finish rm.\n");
                else
                    response(&response_msg, netfd, "rm failed.\n");
                break;
            case CMD_MKDIR:
                printf("cmd_mkdir\n");
                ret = cmd_mkdir(UserInfo, train.value);
                if(ret == 0)
                    response(&response_msg, netfd, "finish mkdir.\n");
                else
                    response(&response_msg, netfd, "mkdir failed.\n");
                break;
            case CMD_RMDIR:
                printf("cmd_rmdir\n");
                ret = cmd_rmdir(UserInfo, train.value);
                if(ret == 0)
                    response(&response_msg, netfd, "finish rmdir.\n");
                else
                    response(&response_msg, netfd, "rmdir failed.\n");
                break;
            case CMD_EXIT:
                printf("Client %d exited\n", netfd);
                break;
            default:
                printf("CMD_UNKNOWN\n");
                response(&response_msg, netfd, "CMD_UNKNOWN");
            }
        }
        // business end
        close(netfd);
    }
}

int makeWorker(threadPool_t *pThreadPool)
{
    for(int i = 0; i < pThreadPool->workerInfo.workerNum; ++i)
    {
        pthread_create(&pThreadPool->workerInfo.workerArr[i], NULL, threadWorker, pThreadPool);
    }
    return 0;
}
